/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package BasaSobol;

import java.io.IOException;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import tinsiec.Message;
import tinsiec.MessageInfo;
import tinsiec.MulticastModule;
import tinsiec.NetworkConfig;
import tinsiec.TCPModule;

/**
 *
 * @author bąsa
 */
public class Main implements Runnable {
    /**
     * Kolejka wiadomości przychodzących wysłanych bezpośrednio do nas
     */
    static BlockingQueue<Message> wiadomosciPrzychodzace = new LinkedBlockingQueue<Message>();

    /**
     * Kolejka wiadomości wychodzących, które chcemy wysłać do konkretnego hosta
     */
    static BlockingQueue<Message> wiadomosciWychodzace = new LinkedBlockingQueue<Message>();

    /**
     * Lista klientów
     */
    static CopyOnWriteArrayList<Klient> klienci = new CopyOnWriteArrayList<Klient>();

    /**
     * Kolejka wiadomości przychodzących wysłanych na multicast
     */
    static BlockingQueue<MessageInfo> wiadomosciPrzychodzaceMulticast = new LinkedBlockingQueue<MessageInfo>();

    /**
     * Kolejka wiadomości wychodzących które chcemy wysłać na multicast
     */
    static BlockingQueue<MessageInfo> wiadomosciWychodzaceMulticast = new LinkedBlockingQueue<MessageInfo>();
        
    static TCPModule modulTCP;
    
    Thread t;
    public static OknoGlowne oknoGlowne = null;
    
    static String mojLogin = new String("user");
    static String mojStatus = new String("Dostepny");
    
    static OknoLogowania oknoLogowania;

    static Timer timer = new Timer();
    
    Main() {
        t = new Thread(this, "watekMain");
        t.start();
    }
    
    static MulticastModule multicast;

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                //MulticastModule multicast;
                try {
                    modulTCP = new TCPModule();

                    modulTCP.setRecivQueue(wiadomosciPrzychodzace);
                    modulTCP.setSendQueue(wiadomosciWychodzace);
                    modulTCP.start();
                    //tinsiec.MessageInfo msg = new MessageInfo(modulXML.wiadomoscONowymKliencie(mojLogin), "");
                    //wiadomosciWychodzaceMulticast.add(msg);

                    Enumeration<NetworkInterface> eni = NetworkConfig.getAvailableInterfaces();
//                    while(eni.hasMoreElements()) {
//                        System.out.println("Interface: " + eni.nextElement().getDisplayName());
//                    }

                    NetworkConfig.setSelectedInterface(NetworkInterface.getByName("eth0"));
                    System.out.println(NetworkConfig.getLocalIP());
                    multicast = new MulticastModule("224.0.0.117", 15500);
                    multicast.setRecvQueue(wiadomosciPrzychodzaceMulticast);
                    multicast.setSendQueue(wiadomosciWychodzaceMulticast);
                    
                    multicast.startListening();
                    
                    new Main();
                    //new OknoTest().setVisible(true);
                    oknoLogowania = new OknoLogowania();
                    oknoLogowania.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    /**
     * Wątek zbierajacy wiadomości z kolejek przychodzących
     * i przekazujący je w odpowiednie miejsca
     */
    public void run() {
        while(true) {
            if(!wiadomosciPrzychodzace.isEmpty()) {
                try {
                    tinsiec.Message msg = wiadomosciPrzychodzace.take();
                    
                    if(modulXML.typWiadomosci(msg.getMessage()) == modulXML.TYPY_WIADOMOSCI.ZWYKLA_WIADOMOSC) {
                        OknoRozmowy o = OknoRozmowy.znajdzWgRozmowcy(Klienci.znajdzLoginPoIP(msg.getIP()));
                        if(o == null) {
                            o = new OknoRozmowy(Klienci.znajdzLoginPoIP(msg.getIP()));
                            o.setVisible(true);
                            // tu trzeba odpalic okienko
                            System.out.println("null");
                        }
                        o.odbierzWiadomosc(Klienci.znajdzLoginPoIP(msg.getIP()) + ": " + modulXML.wyciagnijTrescZWiadomosci(msg.getMessage()));
                
                    }
                    
                    if(modulXML.typWiadomosci(msg.getMessage()) == modulXML.TYPY_WIADOMOSCI.ACK) {
                        if(oknoGlowne == null) {
                            oknoGlowne = new OknoGlowne();
                            oknoGlowne.setVisible(true);
                            oknoLogowania.setVisible(false);
                        }
                        Klienci.dodajKlienta(msg.getIP(), modulXML.wyciagnijLoginZWiadomosci(msg.getMessage()));  
                        Klienci.zmienStatus(msg.getIP(), modulXML.wyciagnijStatusZWiadomosci(msg.getMessage()));
                        oknoGlowne.aktualizujPokazywanychUzytkownikow();
                    }
                    
                    if(modulXML.typWiadomosci(msg.getMessage()) == modulXML.TYPY_WIADOMOSCI.REG) {
                        oknoLogowania.zresetujLogowanie();
                    }
                } catch (InterruptedException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            
            
            
            if(!wiadomosciPrzychodzaceMulticast.isEmpty()) {
                try {
                    tinsiec.MessageInfo msg = wiadomosciPrzychodzaceMulticast.take();
                    System.out.println("przyszla wiadomosc");
                    System.out.println(msg.getContent());
                    if(modulXML.typWiadomosci(msg.getContent()) == modulXML.TYPY_WIADOMOSCI.ZMIANA_STATUSU) {
                        System.out.println("zmiana statusu");
                        if(Klienci.istnieje(msg.getSenderIP())) {
                            System.out.println("klient istnieje");
                            Klienci.zmienStatus(msg.getSenderIP(), modulXML.wyciagnijStatusZWiadomosci(msg.getContent()));
                            oknoGlowne.aktualizujPokazywanychUzytkownikow();
                        }
                    }
                    
                    if(modulXML.typWiadomosci(msg.getContent())==modulXML.TYPY_WIADOMOSCI.NOWY_UZYTKOWNIK) {
                        if((!mojLogin.equals(modulXML.wyciagnijLoginZWiadomosci(msg.getContent()))) && Klienci.znajdzIPPoLoginie(modulXML.wyciagnijLoginZWiadomosci(msg.getContent())).equals("")) {
                            System.out.println("przyszla wiadomosc NOWY UZYTKOWNIK");
                            
                            tinsiec.Message msgACK = new tinsiec.Message(msg.getSenderIP(), modulXML.wiadomoscACK(mojLogin, mojStatus));
                            wiadomosciWychodzace.add(msgACK);
                            System.out.println(msgACK.getMessage());
                            
                            Klienci.dodajKlienta(msg.getSenderIP(),modulXML.wyciagnijLoginZWiadomosci(msg.getContent()));  
                            Klienci.zmienStatus(msg.getSenderIP(), "Dostepny");
                            oknoGlowne.aktualizujPokazywanychUzytkownikow();
                            
                            
                        } else {
                            tinsiec.Message msgREG = new tinsiec.Message(msg.getSenderIP(), modulXML.wiadomoscREG());
                            wiadomosciWychodzace.add(msgREG);
                            System.out.println(msgREG.getMessage());
                        }
                    }
                    
                    if(modulXML.typWiadomosci(msg.getContent()) == modulXML.TYPY_WIADOMOSCI.USUNIETO_UZYTKOWNIKA) {
                        Klienci.usunKlienta(msg.getSenderIP(), modulXML.wyciagnijLoginZWiadomosci(msg.getContent()));
                        oknoGlowne.aktualizujPokazywanychUzytkownikow();
                    }

                    if(modulXML.typWiadomosci(msg.getContent()) == modulXML.TYPY_WIADOMOSCI.PING) {
                        Klienci.resetujCzasBezPinga(msg.getSenderIP());
                    }
                } catch (InterruptedException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            Klienci.sprawdzCzasPinga();
            if(timer.previewTime() > 9.0f) {
                timer.getTime();
                tinsiec.MessageInfo msg = new tinsiec.MessageInfo(modulXML.wiadomoscPING(), "");
                wiadomosciWychodzaceMulticast.add(msg);
            }
        }
    }
}
